package com.wltt.product.ahuthr.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wltt.product.ahuthr.config.exception.BusinessException;
import com.wltt.product.ahuthr.enums.FlowRecordDealResultEnum;
import com.wltt.product.ahuthr.enums.SystemNodeTypeEnum;
import com.wltt.product.ahuthr.holder.UserHolder;
import com.wltt.product.ahuthr.mapper.FlowMapper;
import com.wltt.product.ahuthr.mapper.FlowRecordMapper;
import com.wltt.product.ahuthr.mapper.SystemFlowMapper;
import com.wltt.product.ahuthr.mapper.SystemFlowNodeMapper;
import com.wltt.product.ahuthr.model.ResultData;
import com.wltt.product.ahuthr.model.RspPage;
import com.wltt.product.ahuthr.model.bo.FlowRecordWithSystemNodeBO;
import com.wltt.product.ahuthr.model.bo.ToDoListBO;
import com.wltt.product.ahuthr.model.po.*;
import com.wltt.product.ahuthr.model.vo.*;
import com.wltt.product.ahuthr.service.base.BaseServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @ClassName: FlowServiceImpl
 * @Description: 逻辑服务类<br />
 * 不做业务校验，参数校验统一放到前置的Service中
 * @Date: 2024-09-05 14:58:41
 * @Author yanggl
 */
@Service(value = "flowService")
public class FlowServiceImpl extends BaseServiceImpl<FlowPO, Long> implements FlowService {

    private FlowMapper flowMapper;

    @Resource
    private FlowRecordMapper flowRecordMapper;

    @Resource
    private SystemFlowMapper systemFlowMapper;

    @Resource
    private SystemFlowNodeMapper systemFlowNodeMapper;

    //构造方法
    public FlowServiceImpl(FlowMapper flowMapper) {
        super(flowMapper);
        this.flowMapper = flowMapper;
    }

    /**
     * 流程详情
     *
     * @param flowStepDetailReq
     * @return
     */
    @Override
    public ResultData flowStepDetail(FlowStepDetailReq flowStepDetailReq) {
        Long id = flowStepDetailReq.getId();
        if (null == id) {
            throw new BusinessException("未指定流程", HttpStatus.BAD_REQUEST);
        }
        FlowPO flowPO = flowMapper.queryById(id);
        if (null == flowPO) {
            throw new BusinessException("流程不存在", HttpStatus.BAD_REQUEST);
        }

        FlowStepDetailRsp rsp = new FlowStepDetailRsp();
        BeanUtils.copyProperties(flowPO, rsp);

        SystemFlowPO systemFlowPO = systemFlowMapper.queryById(flowPO.getSystemFlowId());
        rsp.setSystemFlowCode(systemFlowPO.getSystemFlowCode());
        rsp.setSystemFlowName(systemFlowPO.getSystemFlowName());

        List<FlowStepRecordRsp> recordRspList = new ArrayList<>();
        List<SystemFlowNodePO> systemFlowNodePOList = systemFlowNodeMapper.queryBySystemFlowId(systemFlowPO.getId());
        List<FlowRecordPO> flowRecordPOList = flowRecordMapper.queryByFlowId(id);
        Map<Long, FlowRecordPO> flowRecordPOMap = flowRecordPOList
                .stream().collect(Collectors.toMap(FlowRecordPO::getSystemNodeId, obj -> obj, (v1, v2) -> v2));

        for (SystemFlowNodePO systemFlowNodePO : systemFlowNodePOList) {
            FlowStepRecordRsp recordRsp = new FlowStepRecordRsp();
            recordRsp.setSystemNodeId(systemFlowNodePO.getId());
            recordRsp.setSystemNodeName(systemFlowNodePO.getSystemNodeName());
            recordRsp.setSystemNodeOrder(systemFlowNodePO.getSystemNodeOrder());
            recordRsp.setSystemNodeType(systemFlowNodePO.getSystemNodeType());


            if (SystemNodeTypeEnum.RECORD.getCode() == systemFlowNodePO.getSystemNodeType()) {
                FlowRecordPO flowRecordPO = flowRecordPOMap.get(systemFlowNodePO.getId());
                if (null != flowRecordPO) {
                    recordRsp.setFlowRecordId(flowRecordPO.getId());
                    recordRsp.setRecordDate(flowRecordPO.getRecordDate());
                    recordRsp.setDealResult(flowRecordPO.getDealResult());
                } else {
                    recordRsp.setRecordDate(null);
                    recordRsp.setDealResult(FlowRecordDealResultEnum.AWAIT.getCode());
                }
            }
            recordRspList.add(recordRsp);
        }
        recordRspList.sort((o1, o2) -> o1.getSystemNodeOrder()- o2.getSystemNodeOrder());
        rsp.setRecords(recordRspList);
        return ResultData.success(rsp);
    }

    /**
     * 查询流程节点列表
     *
     * @param listFlowStepReq
     * @return
     */
    @Override
    public ResultData listFlowStep(ListFlowStepReq listFlowStepReq) {
        Long id = listFlowStepReq.getId();
        if (null == id) {
            throw new BusinessException("未指定流程", HttpStatus.BAD_REQUEST);
        }
        List<FlowRecordWithSystemNodeBO> flowRecordPOList =  flowRecordMapper.queryFlowRecordWithSystemNodeByFlowId(id);
        List<ListFlowStepRsp> result = Optional.ofNullable(flowRecordPOList).orElse(new ArrayList<>())
                .stream().map(bo -> {
                    ListFlowStepRsp rsp = new ListFlowStepRsp();
                    BeanUtils.copyProperties(bo, rsp);
                    return rsp;
                }).toList();
        return ResultData.success(result);
    }

    /**
     * 查询所有系统流程
     *
     * @return
     */
    @Override
    public ResultData listAllSystemFlow() {
        List<SystemFlowPO> pos = systemFlowMapper.queryAll();

        List<listAllSystemFlowRsp> rsps = Optional.ofNullable(pos).orElse(new ArrayList<>())
                .stream().map(po -> {
                    listAllSystemFlowRsp rsp = new listAllSystemFlowRsp();
                    BeanUtils.copyProperties(po, rsp);
                    return rsp;
                }).toList();
        return ResultData.success(rsps);
    }

    /**
     * 代办列表
     *
     * @param toDoListReq
     * @return
     */
    @Override
    public ResultData toDoList(ToDoListReq toDoListReq) {

        String orderBy = "f.submit_datetime desc";
        Page page = PageHelper.startPage(toDoListReq.getPageNo(), toDoListReq.getPageSize(), orderBy);

        List<Long> roles = UserHolder.getUserRoleIds();
        List<ToDoListBO> toDoListBOS = flowMapper.queryToDoList(toDoListReq.getSystemFlowId(), roles);

        List<ToDoListRsp> rsps = Optional.ofNullable(toDoListBOS).orElse(new ArrayList<>())
                .stream().map(bo -> {
                    ToDoListRsp rsp = new ToDoListRsp();
                    BeanUtils.copyProperties(bo, rsp);
                    return rsp;
                }).toList();

        RspPage rspPage = new RspPage(toDoListReq.getPageNo(), toDoListReq.getPageSize(), rsps, page.getTotal());
        return ResultData.success(rspPage);
    }
}